# -*- coding: UTF-8 -*- #
"""
-------真正的勇士， 敢于直面惨淡的Warning、 敢于正视淋漓的Error-----
@author : 贾鹏博
@file : 22、异常自动截图.py
"""
import time

"""
1、异常截图场景
    增加自动化代码的可测性
    丰富报告

2、异常截图实现
    装饰器
    自动化关键数据记录
        截图
        日志
        page_source
"""

# pytest .\22、异常自动截图.py --alluredir ./allure_report --clean-alluredir
# allure serve ./allure_report

import allure
import time
from selenium import webdriver
from selenium.webdriver.common.by import By


# 目标1 ：实现代码异常的时候，截图/打印page_source
#  ==================================   实现方法：try  catch 配合截图/page_source   ====================================

class TestBaidu:

    def test_baidu(self):
        self.driver = webdriver.Chrome()
        self.driver.get('https://www.baidu.com')
        try:
            self.driver.find_element(By.CSS_SELECTOR, '#su1').click()
        except Exception:
            # 1、截图操作
            timestamp = int(time.time())
            image_path = f'./image/image_{timestamp}.PNG'
            self.driver.save_screenshot(image_path)
            # 2、记录 page_source
            page_source_path = f'./page_source/page_source_{timestamp}.html'
            with open(page_source_path, 'w', encoding='utf-8') as f:
                f.write(self.driver.page_source)
            # 3、将截图放到报告的数据中
            allure.attach.file(image_path, name='picture', attachment_type=allure.attachment_type.PNG)

            # 4、将 page_source 记录到报告中。页面格式是 HTML  ， 源码格式 是 TEXT
            allure.attach.file(page_source_path, name='page_source', attachment_type=allure.attachment_type.HTML)
            # =====================   问题一：异常处理会影响用例本身的结果   解决方案 ： 在 exception 之后再把异常抛出  ==================
            # ===================== 解决方案： 在 exception 之后，再把异常抛出 ========================
            raise Exception

        self.driver.quit()


# =============================    问题二 : 异常捕获处理代码和业务代码无关，不能耦合 ====================================
# 解决方案 : 使用装饰器装饰用例或者相关方法，就不会体现在源码中

# 1、装饰器框架搭建好   2、把相关逻辑嵌套进来
# =======================================


def ui_exception_record(func):
    def inner(*args, **kwargs):
        try:
            # 当被装饰方法/函数发生异常，就会捕获并做数据记录
            return func(*args, **kwargs)
        except Exception:

            # 获取被装饰方法的 self ,也就是实例对象
            # 通过 self 就可以拿到 声明的实例变量
            driver = args[0].driver

            print("抛出异常")
            # 1、截图操作
            timestamp = int(time.time())
            image_path = f'./image/image_{timestamp}.PNG'
            driver.save_screenshot(image_path)
            # 2、记录 page_source
            page_source_path = f'./page_source/page_source_{timestamp}.html'
            with open(page_source_path, 'w', encoding='utf-8') as f:
                f.write(driver.page_source)
            # 3、将截图放到报告的数据中
            allure.attach.file(image_path, name='picture', attachment_type=allure.attachment_type.PNG)

            # 4、将 page_source 记录到报告中。页面格式是 HTML  ， 源码格式 是 TEXT
            allure.attach.file(page_source_path, name='page_source', attachment_type=allure.attachment_type.HTML)
            # 问题一：异常处理会影响用例本身的结果   解决方案 ： 在 exception 之后再把异常抛出
            raise Exception

    return inner


# 问题3：需要通过 driver 实例截图/打印 page_source，装饰器需要先去获取 driver 对象
class TestBaidu1:
    @ui_exception_record
    def test_baidu(self):
        self.driver = webdriver.Chrome()
        self.driver.get('https://www.baidu.com')
        self.driver.find_element(By.CSS_SELECTOR, '#su2').click()
        self.driver.quit()
